﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using UberChess.Structure.Move;

namespace UberChess.Structure.Pieces
{
    [Serializable]
   public class Pawn : IPiece
   {
      private const int MATERIAL_VALUE = 100;
       public Side side;
       private Vector2 currentPosition;
       public bool hasMoved;

       public Pawn(Side side, Vector2 currentPosition)
       {
           this.side = side;
           this.currentPosition = currentPosition;
           hasMoved = false;
       }

       public int GetMaterialValue()
       {
          return MATERIAL_VALUE;
       }

        public Vector2 CurrentPosition
        {
            get
            {
                return currentPosition;
            }
            set
            {
                if (!hasMoved)
                    hasMoved = true;
                currentPosition = value;
            }
        }

        public Rectangle GetSourceRectangle()
       {
           return new Rectangle((side == Side.WHITE ? 0 : Constants.PIECEWIDTH), Constants.PIECEHEIGHT * 5, Constants.PIECEWIDTH, Constants.PIECEHEIGHT);
       }

       public List<PossibleMove> GetPossibleMoves(State state)
       {
           var moves = new List<PossibleMove>();
           var m = new[] {new Vector2(0, -1), new Vector2(-1, -1), new Vector2(1, -1)};

           if (!hasMoved)
           {
                   if (state.GetPieceAtPosition(currentPosition + new Vector2(0, (side == Side.WHITE ? -1 : 1))).GetType() == typeof (Empty))
                   {
                       var pm = new PossibleMove(currentPosition,
                                                 currentPosition + new Vector2(0, (side == Side.WHITE ? -2 : 2)), false);
                       if (state.IsWithinBounds(pm.possibleMove) &&
                           state.GetPieceAtPosition(pm.possibleMove).GetType() == typeof (Empty))
                           moves.Add(pm);
                   }
               
           }

           foreach (var vector2 in m)
           {
               var pos = currentPosition + (side == Side.WHITE ? vector2 : vector2*new Vector2(1, -1));

               if (state.IsWithinBounds(pos))
               {
                   var destination = state.GetPieceAtPosition(pos);
                   if (destination.GetType() == typeof (Empty) && vector2.X == 0)
                       moves.Add(new PossibleMove(currentPosition, pos, false));
                   else if (destination.GetType() != typeof(Empty) && destination.GetSide() != this.side && vector2.X != 0)
                   {
                       moves.Add(new PossibleMove(currentPosition, pos, true));
                   }
               }
           }
           return moves;
       }

       public List<PossibleMove> GetPossibleCaptureMoves(State state)
       {
           var possibleMoves = new List<PossibleMove>();
           var directions = new[] {new Vector2(-1, -1), new Vector2(1, -1)};
           foreach (var direction in directions)
           {
               var pos = currentPosition + (side == Side.WHITE ? direction : direction*new Vector2(1, -1));
               if(state.IsWithinBounds(pos))
                   possibleMoves.Add(new PossibleMove(currentPosition, pos, true));
           }
           return possibleMoves.Where(move => move.isCaptureMove).ToList();
       }

       public Side GetSide()
       {
           return side;
       }

       public void SetCurrentPosition(Vector2 position)
       {
           if (!hasMoved)
               hasMoved = true;

           currentPosition = position;

       }

       public Vector2 GetCurrentPosition()
       {
           return currentPosition;
       }
   }
}
